package com.netty.encodeDecode;

import io.netty.bootstrap.Bootstrap;
import io.netty.channel.Channel;
import io.netty.channel.ChannelHandlerContext;
import io.netty.channel.ChannelInboundHandlerAdapter;
import io.netty.channel.ChannelInitializer;
import io.netty.channel.nio.NioEventLoopGroup;
import io.netty.channel.socket.SocketChannel;
import io.netty.channel.socket.nio.NioSocketChannel;
import io.netty.handler.codec.LengthFieldPrepender;
import io.netty.handler.codec.string.StringDecoder;
import io.netty.handler.codec.string.StringEncoder;

import java.util.Scanner;

/**
 * @author renyitong
 * @version 1.0.0
 * @createTime 2023年08月10日
 * @Description
 */
public class EncodeNettyClient {

    public static void main(String[] args) throws InterruptedException {

        Bootstrap bootstrap = new Bootstrap();   //客户端也是使用Bootstrap来启动,但是不带server了
        bootstrap
                .group(new NioEventLoopGroup())   //客户端就没那么麻烦了，直接一个EventLoop就行，用于处理发回来的数据
                .channel(NioSocketChannel.class)   //客户端肯定就是使用SocketChannel了
                .handler(new ChannelInitializer<SocketChannel>() {   //这里的数据处理方式和服务端是一样的
                    @Override
                    protected void initChannel(SocketChannel channel) throws Exception {
                        // 配置流水线
                        channel.pipeline()
                                .addLast(new StringDecoder())   // 解码器安排
                                .addLast(new ChannelInboundHandlerAdapter() {
                                    @Override
                                    public void channelRead(ChannelHandlerContext ctx, Object msg) throws Exception {
                                        System.out.println(">> 接收到服务器端发回的数据：" + msg);   // 直接接收字符串
                                    }
                                })
                                // 客户端在发送时也需要将长度拼到前面去  在发送的数据前添加一个长度字段，该长度字段占用 4 个字节，记录了发送数据的长度。
                                .addLast(new LengthFieldPrepender(4))
                                .addLast(new StringEncoder());   // 编码器安排
                    }
                });

        Channel channel = bootstrap.connect("localhost", 8080).channel();  //连接后拿到对应的Channel对象
        // 注意上面连接操作是异步的，调用之后会继续往下走，下面我们就正式编写客户端的数据发送代码了
        try (Scanner scanner = new Scanner(System.in)) {    //还是和之前一样，扫了就发
            while (true) {
                System.out.println("<< 请输入要发送给服务端的内容：");
                String text = scanner.nextLine();
                if (text.isEmpty()) {
                    continue;
                }
                channel.writeAndFlush(text);  //通过Channel对象发送数据 , 直接发送字符串就行
            }
        }

    }
}

